import 'dart:typed_data';
import 'package:bluetooth_protocols_plugin/src/huari/base/huari_constant.dart';
import 'package:bluetooth_protocols_plugin/src/huari/base/huari_data.dart';
import 'package:bluetooth_protocols_plugin/src/huari/message/huari_request_body.dart';
import '../../base/message/message_base.dart';
import '../../tools/enums.dart';
import '../../tools/utils.dart';

// 消息
class HuariMessage extends MessageBase {
  // 消息头
  static final Uint8List head =
      Uint8List.fromList([HuariConstant.HEAD1, HuariConstant.HEAD2]);

  // 消息尾
  static final Uint8List foot = Uint8List.fromList([HuariConstant.FOOT]);

  // 命令字
  late Uint8List commandValue;

  // data字段长度
  late Uint8List lengthBytes;

  // 数据段
  late HuariData? data;

  // 校验方式  0：none 无校验、1：parity 奇偶校验、2：crc16 CRC16_MODBUS标准计算、3：crc32 //CRC32计算、8：crc64
  final MessageCheckType checkType = MessageCheckType.crc64;

  // 
  late Uint8List? check;

  // 从 HuariRequestBody 中解析 LorinMessage
  HuariMessage.from(HuariRequestBody requestBody) {
    Uint8List? param = requestBody.param;
    // 命令字
    commandValue = Uint8List.fromList([requestBody.cmd]);
    // 数据段长度
    lengthBytes = Utils.intTo2Bytes(param?.length ?? 0);
    // 数据段
    data = HuariData(param);
    // 计算check
    check = param == null ? Uint8List.fromList([0]) : checkType.checkBytes(param);
  }

  // 从Uint8List中解析 LorinMessage
  HuariMessage.fromList(Uint8List uint8list) {
    if (uint8list.length >= minLength &&
        Utils.equalUint8Lists(uint8list.sublist(0, head.length), head) &&
        Utils.equalUint8Lists(
            Utils.takeLastBytesSafe(uint8list, foot.length), foot)) {
      int offset = 0;
      offset += 2;
      commandValue = uint8list.sublist(offset, offset + 1);
      offset += 1;
      // 数据段长度字节
      lengthBytes = uint8list.sublist(offset, offset + 2);
      // data长度
      int dataLength = Utils.computeDataIntVal(lengthBytes);
      offset += 2;
      // 数据段
      data = HuariData(uint8list.sublist(offset, offset + dataLength));
      offset += dataLength;
      // 提取check
      check = uint8list.sublist(offset, offset + checkType.checkLength());
      if (!checkResult()) {
        throw Exception(
            "【$runtimeType】🟥 Check error: ${uint8list.toString()}");
      }
    } else {
      throw Exception("【$runtimeType】 格式错误");
    }
  }

  // 最小长度
  int get minLength => 7;

  @override
  bool checkResult() {
    return Utils.equalUint8Lists(
        check!, checkType.checkBytes(data?.toBytes() ?? Uint8List(0)));
  }

  @override
  String msgIdentify() {
    return Utils.computeDataIntVal(commandValue).toString();
  }

  @override
  Uint8List toBytes() {
    // Prepare data bytes only once

    // Use a more efficient approach with BytesBuilder
    final builder = BytesBuilder(copy: false);
    builder.add(head);
    builder.add(commandValue);
    builder.add(lengthBytes);
    final dataBytes = data?.toBytes();
    if (dataBytes == null || dataBytes.isEmpty) {
    } else {
      builder.add(dataBytes);
    }
    builder.add(check!);
    builder.add(foot);
    return builder.toBytes();
  }

  @override
  int totalLength() {
    return head.length +
        1 +
        lengthBytes.length +
        (data?.toBytes()?.length ?? 0) +
        check!.length +
        foot.length;
  }
}
